package com.chenju.dynamicagent.aop;

import com.chenju.dynamicagent.domain.MethodNode;
import org.aspectj.lang.ProceedingJoinPoint;

import java.util.Map;
import java.util.Stack;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AroundMethod {
    private static Map<String, Stack<MethodNode>> map = new ConcurrentHashMap<>();
    private static ExecutorService executor = Executors.newSingleThreadExecutor();

    public static void before(ProceedingJoinPoint pjp){
        // 获取当前线程ID
        long threadId = Thread.currentThread().getId();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                // 获取调用的方法信息
                String currentClassName = pjp.getSignature().getDeclaringTypeName();
                String currentMethodName = currentClassName + "." + pjp.getSignature().getName();
                String signature = getSignature(pjp);
                MethodNode currentMethodNode = new MethodNode(String.valueOf(threadId), currentMethodName, signature);
                // 将获取到的方法信息推入Stack中
                pushMap(currentMethodNode);
                // 测试一下
                System.out.println("This Is Before Method: " + currentMethodName);
            }
        });
    }

    public static void after(ProceedingJoinPoint pjp){
        // 获取当前线程ID
        long threadId = Thread.currentThread().getId();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                // 将数据移出Stack

                // 测试一下
                System.out.println("This Is After Method");
            }
        });
    }

    public static String getSignature(ProceedingJoinPoint pjp){
        int index = pjp.getSignature().toShortString().lastIndexOf(".");
        if (index == -1){
            return pjp.getSignature().toShortString();
        }
        return pjp.getSignature().toShortString().substring(index);
    }

    public static void pushMap(MethodNode node){
        Stack<MethodNode> stack = map.get(node.getThreadId());
        if (stack == null){
            stack = new Stack<>();
        }
        stack.push(node);
        map.put(node.getThreadId(), stack);
    }

    public static void popMap(long threadId, String signature){
        Stack<MethodNode> stack = map.get(String.valueOf(threadId));
        if (stack == null || stack.isEmpty()){
            return;
        }
        MethodNode node = stack.pop();
        while (!node.getSignature().equals(signature)){
            if (stack.isEmpty()){
                return;
            }
            node = stack.pop();
        }
        // 保存关系
    }
}
